﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Schema;

namespace UDS.DB.SP1
{
    internal class Script
    {
        public string Path
        {
            get;
            set;
        }

        public string Description
        {
            get;
            set;
        }
    }

    internal class Scripts
    {
        private const string BaseNS = "UDS.DB.SP1.";

        public static IList<Script> GetManifest()
        {
            var xss = GetXSDSchemaSet();
            var settings = new XmlReaderSettings();
            settings.Schemas = xss;
            settings.ValidationType = ValidationType.Schema;

            // Load the xml document
            var doc = new XmlDocument();
            const string Manifest = BaseNS + "Manifest.xml";
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Manifest))
            {
                if (stream == null)
                {
                    throw new InvalidOperationException("The embeded resource '" + Manifest + "' is missing!");
                }
                using (var reader = XmlReader.Create(stream, settings))
                {
                    doc.Load(reader);
                }
            }

            // Parse the document
            var manifest = new List<Script>();
            var np = new XmlNamespaceManager(doc.NameTable);
            np.AddNamespace("v", "http://www.microsoft.com/chzhou/manifest.xsd");

            var nodes = doc.SelectNodes("/v:scripts/v:script", np);
            foreach (XmlElement node in nodes)
            {
                XmlAttribute att = node.Attributes["path"];
                string path = att.Value;

                att = node.Attributes["description"];
                string description = (att == null) ? null : att.Value;

                manifest.Add(new Script { Path = path, Description = description });
            }

            return manifest.AsReadOnly();
        }

        private static XmlSchemaSet GetXSDSchemaSet()
        {
            // Load the xsd schema
            var xss = new XmlSchemaSet();
            const string XsdResourceName = BaseNS + "Manifest.xsd";
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(XsdResourceName))
            {
                if (stream == null)
                {
                    throw new InvalidOperationException("The embeded resource '" + XsdResourceName + "' cannot be found.");
                }
                using (var reader = XmlReader.Create(stream))
                {
                    xss.Add(null, reader);
                }
            }
            if (xss.Count == 0)
            {
                throw new InvalidOperationException("XSD schema have not been properly loaded!");
            }

            return xss;
        }
    }
}
